#include <iostream>
#include <malloc.h>
#include <string.h>

using namespace std;

/*
 * 注意：开发中涉及到模板类，声明和实现需要写在同一个文件中，hpp = h + c/cpp
 * */
//-----------------------------------------------ArrayList声明
template <class E>
class ArrayList{
private:
	E *array = NULL;
	int len = 0;
	int index = 0;

public:
	ArrayList();

	ArrayList(int len);

	~ArrayList();

	ArrayList(const ArrayList &list);

public:
	bool add(E e);

	int size();

	E get(int index);

	E remove(int index);

private:
	void ensureCapacityInternal(int i);

	void grow(int capacity);

};

//-----------------------------------------------ArrayList实现
template <class E>
ArrayList<E>::ArrayList()
{
	
}

template <class E>
ArrayList<E>::ArrayList(int len)
{
	if(len == 0) return;

	this->len = len;
	this->array = (E *)malloc(sizeof(E)*len);
}

template <class E>
ArrayList<E>::~ArrayList()
{
	if(this->array)
	{
		free(this->array);
		this->array = NULL;
	}
}


template <class E>
ArrayList<E>::ArrayList(const ArrayList<E> &list)
{
	this->index = list.index;
	this->len = list.len;
	// 进行深拷贝
	this->array = (E *)malloc(sizeof(E)*len);
	memcpy(this->array,list.array,sizeof(E)*len);
}

template <class E>
E ArrayList<E>::get(int index)
{
	return this->array[index];
}

template <class E>
int ArrayList<E>::size()
{
	return this->index;
}

template <class E>
E ArrayList<E>::remove(int index)
{
	E oldE = this->array[index];
	int move = this->index - index - 1;
	for (int i = 0; i< move; i++) {
		this->array[index + i] = this->array[index + i + 1];
	}
	this->index -= 1;
	return oldE;
}

template <class E>
bool ArrayList<E>::add(E e)
{
	ensureCapacityInternal(index + 1);
	this->array[index++] = e;
	return true;
}

// 判断是否需要调整数组长度
template <class E>
void ArrayList<E>::ensureCapacityInternal(int minCapacity)
{
	if(this->array == NULL)
	{
		minCapacity = 10;
	}

	if(minCapacity - len > 0)
	{
		// 进行扩容操作
		grow(minCapacity);
	}
}

// 对数据进行扩容
template <class E>
void ArrayList<E>::grow(int capacity)
{
	// 计算新数组长度
	int new_len = len + (len >> 1);
	if(capacity - new_len > 0)
	{
		new_len = capacity;
	}

	if(this->array)
	{
		E *arr = (E *)malloc(sizeof(E)*new_len);
		memcpy(arr,this->array,sizeof(E)*index);
		free(this->array);
	
		this->array = arr;
		len = new_len;
	}	
}

int main()
{

	ArrayList<int> *list = new ArrayList<int>(10);
	list->add(1);
	list->add(2);
	for (int i = 0; i < list->size(); i++) {
		cout << list->get(i) << endl;
	}

	return 0;
}


